package ${packageName}.service;
import com.boss.core.jpa.criteria.GenericSpecification;
import com.boss.core.http.rest.errors.BadRequestAlertException;
import ${packageName}.domain.${classInfo.className};
import ${packageName}.dto.${classInfo.className}DTO;
import ${packageName}.repository.${classInfo.className}Repository;
import net.sf.jsqlparser.JSQLParserException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * Service class for managing ${classInfo.className}.
 *
 * @author ${authorName} ${.now?string('yyyy-MM-dd')}
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ${classInfo.className}Service {
    private static final Logger log = LoggerFactory.getLogger(${classInfo.className}Service.class);
    @Autowired
    private ${classInfo.className}Repository ${classInfo.className?uncap_first}Repository;

    @Transactional(readOnly = true)
    public Optional<${classInfo.className}> find(Long id) {
        return ${classInfo.className?uncap_first}Repository.findById(id);
    }

    public ${classInfo.className} create(${classInfo.className}DTO dto) {
        ${classInfo.className} ${classInfo.className?uncap_first} = dto.to${classInfo.className}();
        ${classInfo.className?uncap_first}.setId(null);

        return ${classInfo.className?uncap_first}Repository.save(${classInfo.className?uncap_first});
    }

    public ${classInfo.className} update(${classInfo.className}DTO dto) {
        if (dto.getId() == null) {
            throw new BadRequestAlertException("A  ${classInfo.className} cannot be updated without an ID", "${classInfo.className}", "idBlank");
        }
        if (this.find(dto.getId()).isPresent()) {
            if (log.isDebugEnabled()){
                log.debug("Update  ${classInfo.className}DTO: {}",dto);
            }
            ${classInfo.className} ${classInfo.className?uncap_first} = dto.to${classInfo.className}();
            return ${classInfo.className?uncap_first}Repository.save(${classInfo.className?uncap_first});
        } else {
            throw new BadRequestAlertException("${classInfo.className} does not exist !", "${classInfo.className}", "notExists");
        }

    }

    public ${classInfo.className} modify(${classInfo.className}DTO dto) {
        if (dto.getId() == null) {
            throw new BadRequestAlertException("A  ${classInfo.className} cannot be modified without an ID", "${classInfo.className}", "idBlank");
        }
        if (log.isDebugEnabled()){
            log.debug("Modify ${classInfo.className}DTO: {}",dto);
        }
        return ${classInfo.className?uncap_first}Repository.findById(dto.getId()).map(${classInfo.className?uncap_first} -> {

            dto.to${classInfo.className}(${classInfo.className?uncap_first});
            return ${classInfo.className?uncap_first}Repository.save(${classInfo.className?uncap_first});
        }).orElseGet(() -> {
            throw new BadRequestAlertException("${classInfo.className} does not exist !", "${classInfo.className}", "notExists");
        });
    }

    public void delete(Long id) {
        ${classInfo.className?uncap_first}Repository.findById(id).map(${classInfo.className?uncap_first} -> {
            ${classInfo.className?uncap_first}Repository.delete(${classInfo.className?uncap_first});
            if (log.isDebugEnabled()){
                log.debug("Deleted  ${classInfo.className}: {}",${classInfo.className?uncap_first});
            }
            return id;
        }).orElseGet(() -> {
            throw new BadRequestAlertException("${classInfo.className} does not exist !", "${classInfo.className}", "notExists");
        });

    }


    @Transactional(readOnly = true)
    public Page<${classInfo.className}DTO> list(Pageable pageable) {
        return ${classInfo.className?uncap_first}Repository.findAll(pageable).map(${classInfo.className}DTO::new);
    }


    /**
     *
     * @param whereClause (id=1 or lastModifiedDate > 20190926) and createdBy=admin
     * @param pageable
     * @return
     * @throws JSQLParserException
     */
    @Transactional(readOnly = true)
    public Page<${classInfo.className}DTO> advancedSearch(String whereClause, Pageable pageable) throws JSQLParserException {
        if (StringUtils.isBlank(whereClause)) {
            return ${classInfo.className?uncap_first}Repository.findAll(pageable).map(${classInfo.className}DTO::new);
        }
        GenericSpecification<${classInfo.className}> specification =  GenericSpecification.of(whereClause);
        return ${classInfo.className?uncap_first}Repository.findAll(specification,pageable).map(${classInfo.className}DTO::new);

    }

}
